#include <QWebFrame>
#include <QFile>
#include <QTextCodec>

#include "TemplateViewer.h"

TemplateViewer::TemplateViewer(QWidget *parent) :
    QWebView(parent)
{
    page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);

    jQuery = fileContent(":/jquery.min.js");
    m_highlight = fileContent("highlight.js");
    m_choice = "function choice() {return paths;} choice();";
    m_getPathValue = fileContent("getPathValue.js");
}

void TemplateViewer::applyJQuery()
{
    page()->mainFrame()->evaluateJavaScript(jQuery);
}

QStringList TemplateViewer::pathList()
{
    return page()->mainFrame()->evaluateJavaScript(m_choice).toStringList();
}

void TemplateViewer::highlight(bool state)
{
    QString code = (state ? m_highlight : "stopHighlight = true;");
    page()->mainFrame()->evaluateJavaScript(code);
}

QString TemplateViewer::pathValue(const QString &xpath)
{
    QString code = m_getPathValue.arg( escapeJavascriptString(xpath) );
    QString ret = page()->mainFrame()->evaluateJavaScript(code).toString();
    return ret.trimmed();
}

QString TemplateViewer::pageCodecName()
{
    QMultiMap<QString, QString> meta = page()->mainFrame()->metaData();
    QString charset = "charset";
    QString codecName;
    foreach(QString value, meta)
    {
        if (value.contains( charset, Qt::CaseInsensitive))
        {
            int pos = value.indexOf(charset, 0, Qt::CaseInsensitive);

            if ( pos == -1 )
            {
                codecName = "UTF-8";
                break;
            }

            codecName = value.remove(0, pos + charset.length());
            pos = value.indexOf("=");

            if ( pos == -1 )
            {
                codecName = "UTF-8";
                break;
            }

            codecName = value.remove(0, pos+1);
            codecName = codecName.trimmed();

            break;
        }
    }

    if ( QTextCodec::codecForName( codecName.toStdString().c_str() ) == 0 )
        codecName = "UTF-8";

    return codecName;
}

QString TemplateViewer::fileContent(const QString &fileName)
{
    QFile file;
    file.setFileName(fileName);
    file.open(QIODevice::ReadOnly);
    QString content = file.readAll();
    file.close();

    return content;
}

QString TemplateViewer::escapeJavascriptString(const QString & str)
{
    QString out;
    QRegExp rx("(\\r|\\n|\\\\|\")");
    int pos = 0, lastPos = 0;

    while ((pos = rx.indexIn(str, pos)) != -1)
    {
        out += str.mid(lastPos, pos - lastPos);

        switch (rx.cap(1).at(0).unicode())
        {
        case '\r':
            out += "\\r";
            break;
        case '\n':
            out += "\\n";
            break;
        case '"':
            out += "\\\"";
            break;
        case '\\':
            out += "\\\\";
            break;
        }
        pos++;
        lastPos = pos;
    }
    out += str.mid(lastPos);
    return out;
}

